package com.contexttree.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.UIManager;

import com.contexttree.db.DatabaseManager;
import com.contexttree.filereader.ExeScript;
import com.contexttree.filereader.QueryBuilder;
import com.contexttree.filereader.ReadCsvFile;
import com.contexttree.filereader.ReadTxtFile;
import com.contexttree.utils.FilePrinter;
import com.jgoodies.forms.factories.DefaultComponentFactory;

public class SwingView {
	
	private JFrame frmQueryAndContext;
	private JTextField CsvFilePath;
	private JTextField TxtFilePath;
	
	//Init local variables
	ArrayList<String> csvFile = new ArrayList<String>();
	ArrayList<String> csvFilePos = new ArrayList<String>();
	ArrayList<String> csvFileNeg = new ArrayList<String>();
	ArrayList<String> csvFileConcat = new ArrayList<String>();
	String[][] csvFileSplitted = null;
	ArrayList<String> txtFile = new ArrayList<String>();
	ArrayList<String> txtFileOrdered = new ArrayList<String>();
    ArrayList<String> concatMovie = new ArrayList<String>();
    String[][] tableOrdered = null;
    String executableQueryPos = "";
    String executableQueryNeg = "";
    String FolderPath = "";
    DatabaseManager db = null;
    ArrayList<String> resultSetPos = null;
    ArrayList<String> resultSetNeg = null;
	String scriptname = "./coverageTrsDat.sh";
	String filename = "";
	String minsup = "";
	String minconf = "";
	String maxErrors = "";
	
	int numID = 0;
	int whileselect = 0;
	String pathcsv = null;
	String pathtxt = null;
	String switchsel = null;

	private JTextField databaseName;
	private JTextField databaseUser;
	private JPasswordField databasePass;
	private JTextField tableNameField;
	private JTextField keyTableField;
	private JTextField queryFilePath;
	private JTextField selectQueryField;
	private JTextField FileName;
	private JTextField MinSup;
	private JTextField MinConf;
	private JTextField MaxErrors;

	/**
	 * Launch the application.
	 * @author Filippo Ferri
	 * @author Paolo Barbaglia
	 */
	public static void run() {
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
			SwingView window = new SwingView();
			window.frmQueryAndContext.setVisible(true);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Create the application.
	 */
	public SwingView() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		
		final JButton btnProcessCsv = new JButton("Process CSV");
		btnProcessCsv.setEnabled(false);
		final JButton btnProcessTxt = new JButton("Process TXT");
		btnProcessTxt.setEnabled(false);
		final JButton btnGenQuery = new JButton("Gen query");
		btnGenQuery.setEnabled(false);
		final JButton btnExeQuery = new JButton("Exe query");
		btnExeQuery.setEnabled(false);
		
		frmQueryAndContext = new JFrame();
		frmQueryAndContext.setTitle("Query and Context Tree Analyzer");
		frmQueryAndContext.setBounds(100, 100, 931, 540);
		frmQueryAndContext.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		JPanel panel = new JPanel();
		frmQueryAndContext.getContentPane().add(panel, BorderLayout.CENTER);
		panel.setLayout(null);
		
		JLabel LabelCsvFilePath = DefaultComponentFactory.getInstance().createLabel("CSV");
		LabelCsvFilePath.setBounds(10, 14, 39, 14);
		panel.add(LabelCsvFilePath);
		
		CsvFilePath = new JTextField();
		CsvFilePath.setBounds(45, 11, 411, 20);
		panel.add(CsvFilePath);
		CsvFilePath.setColumns(40);
		
		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setBounds(10, 199, 895, 294);
		panel.add(scrollPane);
		
		final JTextArea txtLogPanel = new JTextArea();
		scrollPane.setViewportView(txtLogPanel);
		
		JButton BtnFileCsvSelect = new JButton("...");
		BtnFileCsvSelect.setBounds(466, 10, 23, 23);		
		BtnFileCsvSelect.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				final JFileChooser fc = new JFileChooser();
				int returnVal = fc.showOpenDialog(fc);
				if (returnVal == JFileChooser.APPROVE_OPTION) {
	                File file = fc.getSelectedFile();
	                //This is where a real application would open the file.
	                CsvFilePath.setText(file.getAbsolutePath());
	                btnProcessCsv.setEnabled(true);
				}
			}
		});
		panel.add(BtnFileCsvSelect);
		
		JLabel LabelTxtFilePath = DefaultComponentFactory.getInstance().createLabel("TXT");
		LabelTxtFilePath.setBounds(10, 39, 39, 14);
		panel.add(LabelTxtFilePath);
		
		TxtFilePath = new JTextField();
		TxtFilePath.setBounds(45, 36, 411, 20);
		TxtFilePath.setToolTipText("Seleziona file");
		TxtFilePath.setColumns(40);
		panel.add(TxtFilePath);
		
		JButton BtnFileTxtSelect = new JButton("...");
		BtnFileTxtSelect.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				final JFileChooser fc = new JFileChooser();
				int returnVal = fc.showOpenDialog(fc);
				if (returnVal == JFileChooser.APPROVE_OPTION) {
	                File file = fc.getSelectedFile();
	                //This is where a real application would open the file.
	                TxtFilePath.setText(file.getAbsolutePath());
	                btnProcessTxt.setEnabled(true);
	            }
			}
		});
		BtnFileTxtSelect.setBounds(466, 35, 23, 23);
		panel.add(BtnFileTxtSelect);
		
		JLabel lblFileName = new JLabel("File name");
		lblFileName.setBounds(555, 63, 87, 17);
		panel.add(lblFileName);
		
		JLabel lblMinSup = new JLabel("MinSup");
		lblMinSup.setBounds(555, 91, 87, 14);
		panel.add(lblMinSup);
		
		JLabel lblMinConf = new JLabel("MinConf");
		lblMinConf.setBounds(555, 121, 87, 14);
		panel.add(lblMinConf);
		
		JLabel lblMaxErrors = new JLabel("Max Errors");
		lblMaxErrors.setBounds(555, 146, 87, 14);
		panel.add(lblMaxErrors);
		
		FileName = new JTextField();
		FileName.setBounds(617, 60, 288, 20);
		panel.add(FileName);
		FileName.setColumns(10);
		
		MinSup = new JTextField();
		MinSup.setBounds(617, 88, 288, 20);
		panel.add(MinSup);
		MinSup.setColumns(10);
		
		MinConf = new JTextField();
		MinConf.setBounds(617, 118, 288, 20);
		panel.add(MinConf);
		MinConf.setColumns(10);
		
		MaxErrors = new JTextField();
		MaxErrors.setBounds(617, 143, 288, 20);
		panel.add(MaxErrors);
		MaxErrors.setColumns(10);
		
		JButton btnGenViews = new JButton("Insert elements for creating views");
		btnGenViews.setBounds(614, 171, 291, 23);
		panel.add(btnGenViews);
		
		btnGenViews.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				filename = FileName.getText();
				minsup = MinSup.getText();
				minconf = MinConf.getText();
				maxErrors = MaxErrors.getText();
			}
		});
		
		
		btnProcessCsv.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				txtLogPanel.append("====================== Conta record ======================\n");
				csvFile = ReadCsvFile.read(CsvFilePath.getText().toString());
				
		        if (csvFile != null){
		        	numID = ReadCsvFile.countId(csvFile);
		        	csvFileSplitted = ReadCsvFile.checkRecords(csvFile, numID);
		        	int numId = ReadCsvFile.countId(csvFile);
		        	txtLogPanel.append("Il file � stato letto correttamente e contiene " + numID + " record distinti\n");
					txtLogPanel.append("====================== Riordina csv ======================\n");
					ReadCsvFile.print(csvFileSplitted,csvFile,numId,txtLogPanel);
		        }
		        txtLogPanel.append("==========================================================\n");
			}
		});
		btnProcessCsv.setBounds(136, 87, 95, 23);
		panel.add(btnProcessCsv);
		
		btnProcessTxt.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				
				//l'utente sceglie il percorso dove verranno salvati i file di output
				final JFileChooser folder = new JFileChooser();
				folder.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
				int returnVal = folder.showOpenDialog(folder);
				if (returnVal == JFileChooser.APPROVE_OPTION) {
					File file = folder.getSelectedFile();
					FolderPath = (file.getAbsolutePath());
		        }
				
				txtLogPanel.append("====================== Riordina txt ======================\n");
				txtFile = ReadTxtFile.read(TxtFilePath.getText().toString());
				txtFileOrdered = ReadTxtFile.order(txtFile);
				for(int i=0;i<txtFileOrdered.size();i++){
					txtLogPanel.append(txtFileOrdered.get(i)+"\n");
				}
				txtLogPanel.append("=============== Riordina txt per copertura ===============\n");
				ReadTxtFile.orderViews(csvFileSplitted, txtFileOrdered, txtLogPanel);
				txtLogPanel.append("=================== Elimina ridondanze ===================\n");
				String table[][] = ReadTxtFile.removeRedundantViews(txtFileOrdered, csvFileSplitted, txtLogPanel);
				FilePrinter.printViews("ViewsOrderedWithoutRedundances.txt", FolderPath, table);
		        txtLogPanel.append("==================== Conta occorrenze ====================\n");
				txtFile = ReadTxtFile.read(TxtFilePath.getText().toString());
		        txtFileOrdered = ReadTxtFile.order(txtFile);
		        tableOrdered = ReadTxtFile.orderRecords(csvFileSplitted, txtFileOrdered, txtLogPanel);
		        txtLogPanel.append("==========================================================\n");
			}
		});
		btnProcessTxt.setBounds(241, 87, 95, 23);
		panel.add(btnProcessTxt);
		
		databaseName = new JTextField("movielensesteso");
		databaseName.setColumns(40);
		databaseName.setBounds(555, 11, 253, 20);
		panel.add(databaseName);
		
		JLabel lblDatabaseName = DefaultComponentFactory.getInstance().createLabel("DB name");
		lblDatabaseName.setBounds(499, 14, 61, 14);
		panel.add(lblDatabaseName);
		
		databaseUser = new JTextField();
		databaseUser.setColumns(40);
		databaseUser.setBounds(555, 36, 87, 20);
		panel.add(databaseUser);
		
		databasePass = new JPasswordField();
		databasePass.setColumns(40);
		databasePass.setBounds(713, 36, 95, 20);
		panel.add(databasePass);
		
		JLabel lblUserName = DefaultComponentFactory.getInstance().createLabel("User");
		lblUserName.setBounds(499, 39, 61, 14);
		panel.add(lblUserName);
		
		JLabel lblUserPassword = DefaultComponentFactory.getInstance().createLabel("Password");
		lblUserPassword.setBounds(652, 39, 51, 14);
		panel.add(lblUserPassword);
		
		final JButton dbConnBtn = new JButton("Connect");
		dbConnBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				db = new DatabaseManager(databaseName.getText(), databaseUser.getText(), databasePass.getText());
				if(db.isConnected()==false){
					db.connect();
					if (!db.connect()) {
						txtLogPanel.append("Errore durante la connessione.\n");
						txtLogPanel.append(db.getError());
					}else{
						txtLogPanel.append("====================== DB Status ======================\n");
						txtLogPanel.append("Connessione OK\n");
						databaseName.setBackground(Color.GREEN);
						btnExeQuery.setEnabled(true);
					}
				}
			}
		});
		dbConnBtn.setBounds(818, 10, 87, 23);
		panel.add(dbConnBtn);
		
		JLabel lblSelectQuery = new JLabel("Select query");
		lblSelectQuery.setBounds(10, 146, 78, 14);
		panel.add(lblSelectQuery);
		
		tableNameField = new JTextField("movies");
		tableNameField.setColumns(40);
		tableNameField.setBounds(81, 118, 190, 20);
		panel.add(tableNameField);
		
		JLabel lblNewLabel = new JLabel("Table name");
		lblNewLabel.setBounds(10, 121, 78, 14);
		panel.add(lblNewLabel);
		
		keyTableField = new JTextField("MovieID");
		keyTableField.setColumns(40);
		keyTableField.setBounds(344, 118, 201, 20);
		panel.add(keyTableField);
		
		JLabel lblKeyField = new JLabel("Key field");
		lblKeyField.setBounds(290, 121, 61, 14);
		panel.add(lblKeyField);
		
		queryFilePath = new JTextField();
		queryFilePath.setToolTipText("Seleziona file");
		queryFilePath.setColumns(40);
		queryFilePath.setBounds(45, 60, 411, 20);
		panel.add(queryFilePath);
		
		JButton button = new JButton("...");
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				final JFileChooser fc = new JFileChooser();
				int returnVal = fc.showOpenDialog(fc);
				if (returnVal == JFileChooser.APPROVE_OPTION) {
	                File file = fc.getSelectedFile();
	                //This is where a real application would open the file.
	                queryFilePath.setText(file.getAbsolutePath());
	                btnGenQuery.setEnabled(true);
	            }
			}
		});
		button.setBounds(466, 59, 23, 23);
		panel.add(button);
		
		JLabel lblQueryFileTxt = new JLabel("QUE");
		lblQueryFileTxt.setBounds(10, 64, 39, 14);
		panel.add(lblQueryFileTxt);
		
		btnGenQuery.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				String queryString = QueryBuilder.readQueryFile(queryFilePath.getText());
				txtLogPanel.append("====================== Genera query (IN) ======================\n");
				executableQueryPos = QueryBuilder.buildQuery(tableNameField.getText(), keyTableField.getText(), queryString, selectQueryField.getText(), "IN");
				txtLogPanel.append(executableQueryPos);
				txtLogPanel.append("\n==================== Genera query (NOT IN) ====================\n");
				executableQueryNeg = QueryBuilder.buildQuery(tableNameField.getText(), keyTableField.getText(), queryString, selectQueryField.getText(), "NOT IN");
				txtLogPanel.append(executableQueryNeg);
				txtLogPanel.append("\n===============================================================\n");
			}
		});
		btnGenQuery.setBounds(346, 87, 95, 22);
		panel.add(btnGenQuery);
		
		JScrollPane scrollPane_1 = new JScrollPane();
		scrollPane_1.setBounds(81, 146, 464, 42);
		panel.add(scrollPane_1);
		
		selectQueryField = new JTextField("select * from movies where Country like '%USA%'");
		scrollPane_1.setViewportView(selectQueryField);
		selectQueryField.setColumns(40);
		
		JButton btnClearLogger = new JButton("Clear LOG");
		btnClearLogger.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				txtLogPanel.setText("");
			}
		});
		btnClearLogger.setBounds(31, 87, 95, 23);
		panel.add(btnClearLogger);
		
		btnExeQuery.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if(db.isConnected()==true){
					
					//l'utente sceglie il percorso dove verranno salvati i file di output
					final JFileChooser folder = new JFileChooser();
					folder.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
					int returnVal = folder.showOpenDialog(folder);
					if (returnVal == JFileChooser.APPROVE_OPTION) {
						File file = folder.getSelectedFile();
						FolderPath = (file.getAbsolutePath());
			        }
										
					txtLogPanel.append("====================== Esegui query (IN) ======================\n");
					resultSetPos = db.executeQuery(executableQueryPos);
					String pathPos = FilePrinter.printResultQueryOnFile(filename + "All" + "_positive" + ".csv",FolderPath,resultSetPos);
					txtLogPanel.append("File creato: " + pathPos + "\n");
					txtLogPanel.append("Tracciato file: " + resultSetPos.get(0)+"\n");
					txtLogPanel.append("==================== Esegui query (NOT IN) ====================\n");
					resultSetNeg = db.executeQuery(executableQueryNeg);
					String pathNeg = FilePrinter.printResultQueryOnFile(filename + "All" + "_unlabeled" + ".csv",FolderPath,resultSetNeg);
					txtLogPanel.append("File creato: " + pathNeg + "\n");
					txtLogPanel.append("Tracciato file: " + resultSetNeg.get(0)+"\n");
					
					
					//creazione del pannello per l'inserimento dei dati riguardanti le viste
					JPanel panelForViews = new JPanel();
					frmQueryAndContext.getContentPane().add(panelForViews, BorderLayout.CENTER);
					panelForViews.setLayout(null);				
										
					csvFilePos=ReadCsvFile.read(pathPos);
					csvFileNeg=ReadCsvFile.read(pathNeg);
					csvFilePos=ReadCsvFile.addFieldPositive(csvFilePos);
					csvFileNeg=ReadCsvFile.addFieldUnlabeled(csvFileNeg);
					csvFileConcat=ReadCsvFile.concatenate(csvFilePos, csvFileNeg);
					numID=ReadCsvFile.countId(csvFileConcat);
					csvFileSplitted=ReadCsvFile.checkRecords(csvFileConcat, numID);
					csvFileSplitted=ReadCsvFile.arrangeId(csvFileSplitted);
					csvFileSplitted=ReadCsvFile.eliminateHeaders(csvFileSplitted);
					FilePrinter.printTable(filename + "All" + ".csv",FolderPath, csvFileSplitted);
					csvFileSplitted=ReadCsvFile.convertToNumber(csvFileSplitted,FolderPath,filename);
					
					try {
						ExeScript.execute(scriptname, filename, minsup, minconf, maxErrors);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
					txtFile = ReadTxtFile.read("./visteTesto_minsup" + minsup +"_minconf" + minconf + "_maxerrors"+ maxErrors + "_" + filename + ".txt");
					txtFileOrdered = ReadTxtFile.order(txtFile);
					
					numID = ReadCsvFile.countId(csvFilePos);
		        	csvFileSplitted = ReadCsvFile.checkRecords(csvFilePos, numID);
					String table[][] = ReadTxtFile.removeRedundantViews(txtFileOrdered, csvFileSplitted, txtLogPanel);
					FilePrinter.printViews(filename + "All_" + "ViewsOrderedWithoutRedundances.txt", FolderPath, table);
					tableOrdered = ReadTxtFile.orderRecords(csvFileSplitted, txtFileOrdered, txtLogPanel);
					FilePrinter.printTable(filename + "All_" + "PositiveRecordsOrdered.txt", FolderPath, tableOrdered);
					
					ExeScript.deleteFiles(filename, minsup, minconf, maxErrors, FolderPath);
				}
			}
		});
		btnExeQuery.setBounds(451, 87, 95, 22);
		panel.add(btnExeQuery);
		
		JButton btnDisconnect = new JButton("Disconnect");
		btnDisconnect.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if(db.isConnected()==true){
					db.disconnect();
					txtLogPanel.append("====================== DB Status ======================\n");
					txtLogPanel.append("Disconnessione OK\n");
					databaseName.setBackground(Color.RED);
				}
			}
		});
		btnDisconnect.setBounds(818, 35, 87, 23);
		panel.add(btnDisconnect);
			
		JButton btnNewButton = new JButton("Seleziona file");
		btnNewButton.setBounds(432, 10, 95, 23);
		btnNewButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				final JFileChooser fc = new JFileChooser();
				int returnVal = fc.showOpenDialog(fc);
				if (returnVal == JFileChooser.APPROVE_OPTION) {
	                File file = fc.getSelectedFile();
	                TxtFilePath.setText(file.getName());
	            } else {
	            	TxtFilePath.setText("Seleziona un file");
	            }
			}
		});
		
	}
}